﻿
using System;
using System.Drawing;
using System.Runtime.InteropServices;
using System.Text;
using System.Windows.Forms;

using HWND = System.IntPtr;
using n_ISPcommon;

namespace n_CodeBox
{
	//****************************************************************
	//文件显示窗口
	public static class CodeBox
	{
		static RichTextBox CodeText;
		static Label LineLabel;
		
		//用DLL函数
		[DllImport("user32")]
		static extern int SendMessage(HWND hwnd, int wMsg, int wParam, IntPtr lParam);
		const int WM_SETREDRAW = 0x000B;
		
		public static void Init( RichTextBox r, Label l )
		{
			LineLabel = l;
			LineLabel.Paint += new PaintEventHandler( LineLabel_Paint );
			
			CodeText = r;
			CodeText.MouseDown += new MouseEventHandler( CodeText_MouseDown );
			CodeText.KeyPress += new KeyPressEventHandler( CodeText_KeyPress );
			CodeText.VScroll += new EventHandler( CodeText_VScroll );
			CodeText.TextChanged += new EventHandler( CodeText_TextChanged );
		}
		
		//判断缓冲区是否为空
		public static bool BufferIsEmpty()
		{
			if( CodeText.Text == "" ) {
				return true;
			}
			return false;
		}
		
		//设置打开的文本
		public static void SetCodeText( string Code )
		{
			CodeText.Text = "";
			CodeText.Refresh();
			CodeText.Text = ISPcommon.SwitchCode( Code );
		}
		
		//转换当前缓冲区文本为二维数组
		public static string GetText()
		{
			return CodeText.Text;
		}
		
		//=======================================
		//用于读取Flash
		static string TextBuffer;
		static string TextChar;
		
		//清除当前缓冲区,为添加函数作准备
		public static void Clear()
		{
			CodeText.Text = "";
			TextBuffer = null;
			TextChar = null;
			CodeText.Refresh();
		}
		
		//添加一段机器码
		public static void Add( byte[] Buffer )
		{
			string Number = "0123456789ABCDEF";
			for( int i = 0; i < Buffer.Length; ) {
				string SHex = " " + Number[ Buffer[ i ] / 16 ] + Number[ Buffer[ i ] % 16 ];
				TextBuffer += SHex;
				if( Buffer[ i ] >= 32 && Buffer[ i ] <= 126 ) {
					TextChar += (char)Buffer[ i ];
				}
				else {
					TextChar += '.';
				}
				++i;
				if( i % 16 == 0 ) {
					TextBuffer += "    " + TextChar + "\n";
					TextChar = null;
				}
			}
		}
		
		//显示添加完成的内容
		public static void ShowBuffer()
		{
			CodeText.Text = TextBuffer;
		}
		
		//=======================================
		//文本改变
		static void CodeText_TextChanged(object sender, EventArgs e)
		{
			LineLabel.Invalidate();
		}
		
		//滚动条移动
		static void CodeText_VScroll(object sender, EventArgs e)
		{
			int p = CodeText.GetPositionFromCharIndex( 0 ).Y % ( CodeText.Font.Height + 1 );
			LineLabel.Invalidate();
		}
		
		//画行号
		static void LineLabel_Paint( object sender, PaintEventArgs e )
		{
			Point pos = new Point( 0, 0 );
			int firstIndex = CodeText.GetCharIndexFromPosition( pos );
			int firstLine = CodeText.GetLineFromCharIndex( firstIndex );
			pos.X = CodeText.ClientRectangle.Width;
			pos.Y = CodeText.ClientRectangle.Height;
			int endIndex = CodeText.GetCharIndexFromPosition( pos );
			int endLine = CodeText.GetLineFromCharIndex( endIndex );
			
			for( int i = firstLine; i <= endLine; ++i ) {
				int y = CodeText.GetPositionFromCharIndex( CodeText.GetFirstCharIndexFromLine( i ) ).Y;
				Rectangle rec = new Rectangle( 0, y, CodeText.Width, CodeText.Font.Height );
				string LineLabel = ( i * 16 ).ToString( "X" ).PadLeft( 5, '0' );
				e.Graphics.DrawString( LineLabel, CodeText.Font, Brushes.DarkSlateGray, rec );
			}
		}
		
		//鼠标点击
		static void CodeText_MouseDown(object sender, MouseEventArgs e)
		{
			int LineFirstIndex = CodeText.GetFirstCharIndexOfCurrentLine();
			int StartIndex = CodeText.SelectionStart - LineFirstIndex;
			if( StartIndex != 0 && StartIndex <= 3 * 16 ) {
				CodeText.SelectionLength = 1;
				if( StartIndex % 3 == 0 ) {
					--CodeText.SelectionStart;
				}
			}
			else {
				CodeText.SelectionLength = 0;
			}
		}
		
		//按键事件
		static void CodeText_KeyPress(object sender, KeyPressEventArgs e)
		{
			if( CodeText.Text == "" ) {
				return;
			}
			SendMessage( CodeText.Handle, WM_SETREDRAW, 0, IntPtr.Zero );
			int LineFirstIndex = CodeText.GetFirstCharIndexOfCurrentLine();
			int StartIndex = CodeText.SelectionStart - LineFirstIndex;
			if( StartIndex < 3 * 16 && CodeText.SelectionLength == 1 ) {
				if( e.KeyChar >= '0' && e.KeyChar <= '9' ||
				   e.KeyChar >= 'a' && e.KeyChar <= 'f' ||
				   e.KeyChar >= 'A' && e.KeyChar <= 'F' ) {
					
					CodeText.SelectedText = e.KeyChar.ToString().ToUpper();
					if( StartIndex != 3 * 16 - 1 ) {
						if( StartIndex % 3 == 2 ) {
							++CodeText.SelectionStart;
						}
						CodeText.SelectionLength = 1;
					}
					T.T.ISPBox.SetLockMessage( "changed" );
				}
			}
			//修改字符显示
			int Line = CodeText.GetLineFromCharIndex( CodeText.SelectionStart );
			if( Line == CodeText.Lines.Length - 1 ) {
				SendMessage( CodeText.Handle, WM_SETREDRAW, 1, IntPtr.Zero );
				CodeText.Invalidate();
				return;
			}
			string SLine = CodeText.Lines[ Line ];
			string HEXString = SLine.Remove( 3 * 16 );
			string HEX = HEXString.Trim( ' ' );
			string[] Cut = HEX.Split( ' ' );
			string HEXChar = "";
			for( int i = 0; i < Cut.Length; ++i ) {
				int Value = int.Parse( Cut[ i ], System.Globalization.NumberStyles.HexNumber );
				if( Value >= 32 && Value <= 126 ) {
					HEXChar += (char)Value;
				}
				else {
					HEXChar += '.';
				}
			}
			int Start = CodeText.SelectionStart;
			int Length = CodeText.SelectionLength;
			CodeText.SelectionStart = CodeText.GetFirstCharIndexOfCurrentLine();
			CodeText.SelectionLength = CodeText.Lines[ Line ].Length;
			CodeText.SelectedText = HEXString + "    " + HEXChar;
			CodeText.SelectionStart = Start;
			CodeText.SelectionLength = Length;
			SendMessage( CodeText.Handle, WM_SETREDRAW, 1, IntPtr.Zero );
			CodeText.Invalidate();
		}
	}
}
